#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
#include <thread>

class ThreadData
{
public:
    ThreadData()
    {
    }

    void Init(const std::string &name, int a, int b)
    {
        _name = name;
        _a = a;
        _b = b;
    }

    void Excute() { _result = _a + _b; }

    int Result() { return _result; }

    std::string Name() { return _name; }

    void SetId(pthread_t tid) { _tid = tid; }

    pthread_t Id() { return _tid; }

    int A() { return _a; }
    int B() { return _b; }

    ~ThreadData()
    {
    }

private:
    std::string _name;
    int _a;
    int _b;
    int _result;
    pthread_t _tid;
};

// 线程的局部存储
__thread int gval;

std::string toHex(pthread_t tid)
{
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%lx", tid);
    return buffer;
}

void *routine(void *args)
{
    // std::string name = static_cast<const char *>(args);
    ThreadData *td = static_cast<ThreadData *>(args);

    while (true)
    {
        std::cout << "我是新线程，我的名字是: " << td->Name() << ", my tid is : " << toHex(pthread_self()) << std::endl;
        gval++;
        td->Excute();
        ::sleep(1);
        break;
    }
    return td;
    // return (void*)10;      // 线程退出方式1: 线程入口函数return，表示线程退出
    //  这里的 10 被当作一个地址值（尽管它实际上很可能不是一个有效的地址），并且被强制转换为一个 void* 类型的指针。
}

#define NUM 10

int main()
{
    ThreadData td[NUM];
    // 初始化
    for(int i = 0; i < NUM; i++)
    {
        char id[64];
        snprintf(id, sizeof(id), "thread-%d", i);
        td[i].Init(id, i * 10, i * 20);
    }
 
    // 创建多线程
    for(int i = 0; i < NUM; i++)
    {
        pthread_t id;
        pthread_create(&id, nullptr, routine, &td[i]);
        td[i].SetId(id);
    }

    // 等待多个线程
    for(int i = 0; i < NUM; i++)
    {
        pthread_join(td[i].Id(), nullptr);
    }

    // 汇总处理结果
    for(int i = 0; i < NUM; i++)
    {
        printf("td[%d]: %d+%d=%d[%ld]\n", i, td[i].A(), td[i].B(), td[i].Result(), td[i].Id());
    }









    // pthread_t tid1;
    // ThreadData *td = new ThreadData("thread-1", 10, 20);
    // pthread_create(&tid1, nullptr, routine1, td); // 传参传递对象

    // ThreadData* rtd = nullptr;
    // int n = pthread_join(tid1, (void**)&rtd);
    // if (n != 0)
    // {
    //     std::cerr << "join error: " << n << ", " << strerror(n) << std::endl;
    // }

    // std::cout << "join success!, ret: "<< rtd->Result() << std::endl;   // ret的地址值是10，不能解引用，没有明确的对象类型
    // delete td;


















    // int *p = new int(100);    // p是指针变量 存着指针 地址就是指针
    // std::cout << (long long)p << std::endl;
























    // // std::cout << "new thread id: " << tid << std::endl;
    // printf("new thread id : 0x%lx\n", tid);

    // while (true)
    // {
    //     std::cout << "我是main线程..." << std::endl;
    //     sleep(1);
    // }

    return 0;
}